package com.redribbon.droidnoise;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import android.net.DhcpInfo;
import android.net.wifi.WifiManager;
import android.util.Log;


//new NoiseServer((WifiManager) getSystemService(Context.WIFI_SERVICE))
//.start();

// global objects for wifi

public class NoiseServer extends Thread
{	
	private WifiManager mWifi;
	private final String TAG = "SERVER-NET";
	private DatagramSocket socket = null;
	
	NoiseServer(WifiManager wifi) 
	{
		mWifi = wifi; // set obj

		try {
			Log.d(TAG, "Port Numbers: (Client, Server) = " + NoiseConstants.client_port_number + ", " + NoiseConstants.server_port_number);
			socket = new DatagramSocket(NoiseConstants.server_port_number);
			socket.setBroadcast(true);
			// socket.setSoTimeout(NoiseConstants.SOCKET_RECV_TIMEOUT);

		} catch (IOException e) {
			Log.e(TAG, "socket create failed", e);
		}
	}
	
	/**
	* Calculate the broadcast IP we need to send the packet along. If we send it
	* to 255.255.255.255, it never gets sent. I guess this has something to do
	* with the mobile network not wanting to do broadcast.
	*/
	private InetAddress getBroadcastAddress() throws IOException {
		DhcpInfo dhcp = mWifi.getDhcpInfo();
		if (dhcp == null) {
			Log.d(TAG, "Could not get dhcp info");
			return null;
		}

		// generate broadcast address from ip/netmask
		// then make the last bit of netmask (host portion to be all 1's)
		int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
		byte[] quads = new byte[4];
		for (int k = 0; k < 4; k++)
		{
			// take the octets and take put it into the byte array
			quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
		}
		return InetAddress.getByAddress(quads);
	}
	
	// true if okay, false if error
	public boolean sendData(byte[] array, int len)	//MIGHT BE VERY INEFFICIENT
	{
		// TODO: check len doesn't exceed 64k
		Log.d(TAG, "sendData() starting!");
		
		
		try {
			// TODO: don't know whether using client/server port, they should be the same !!!
			DatagramPacket packet = new DatagramPacket(array, len, getBroadcastAddress(), NoiseConstants.server_port_number);
		    socket.send(packet);
		    Log.d(TAG, "sendData() len was " + len);
		} catch (IOException e) {
			Log.e(TAG, "sendData() failed", e);
			return false;
		}
		
		return true;
	}
	
	public void resetSocket()
	{
		// this will close any open socket
		// it does nothing if nothing is open
		if (socket == null) return;
		
		socket.close();
	
	}
}